
#include <sys/ioctl.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <sys/io.h>
#include <unistd.h>
using namespace std;

#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include "DMATest.h"

//struct timeval
//{
//	time_t tv_sec;
//	suseconds_t tv_usec;
//};

void Read_FPGA_VER()
{      
	    
		int ret;
		int vernum;
		
//	    ret = ioctl(g_fd, FPGAVERSION, vernum);
 ret = ioctl(g_fd, FPGAVERSION, &vernum);
		if ( ret == 0 )
		{
			printf("READ FPGAV ERSION  = %x\n",vernum);
		}
		else
		{
			printf("READ FPGAV ERSION  ERROR = %d\n", ret);
			//return  ret;
		}
		
		//return vernum;
}


unsigned char Read_Chan_NUM()
{      
	    
		int ret;
		unsigned char channum;
		
	      ret = ioctl(g_fd, ID_NUM, &channum);
		if ( ret == 0 )
		{
			//printf("READ Chan number  = %x\n",channum);
		}
		else
		{
			printf("READ Chan number ERROR = %d\n", ret); 
                        return -1;
			//return  ret;
		}
		
	  return channum;
}



void tOpen()
{
	    char fileName[32];

		sprintf(fileName, "/dev/xbmd");
		g_fd = open(fileName, O_RDWR);

		if ( g_fd < 0 )
		{
			printf("open %s ERROR\n", fileName);
		}
		else
		{
			printf("open %s OK\n", fileName);
		}
	
}

int Read_USER_DMA_Status( )
{      
	    int Status;
		int ret;
	    ret = ioctl(g_fd, DMASTATUS, &Status);
		if ( ret == 0 )
		{
			printf("READ DMA STATUS = %d\n",Status);
		}
		else
		{
			printf("READ DMA STATUS ERROR = %d\n", ret);
		}
}



void tRecv()
{
	    //xbmd_frame frame;
		
		unsigned char buf[buf_size+1];
	
		int ret = read(g_fd, (void*)&buf, sizeof(buf));
                
            //printf("tRecv STATUS = %d\n", ret);
                  
		if ( ret == 0 )
		{         
			
                       /*
			printf("chan id :0x%x \n", buf[0]);
			for(int i = 1; i< sizeof(buf); i++)
			{	
				printf("0x%x ", buf[i]);
			}
			printf("\n");
                       */
		}
		else
		{
			printf("recv ERROR = %d\n", ret);
		}
}


void tInit( )
{
	    unsigned int io; 
	
	    int ret;
        // reset xbmd board
      /*
	    ret = ioctl(g_fd, INITRST, &io);
		if ( ret == 0 )
		{
			printf("reset xbmd board successful! \n");
		}
		else
		{
			printf("reset xbmd board ERROR = %d\n", ret);
		}
        */
		
	   //set write dma tlp size
	    ret = ioctl(g_fd, WRWDMATLPS, tlp_size);
		if ( ret == 0 )
		{
			printf("write dma tlp size = %d\n", tlp_size);
		}
		else
		{
			printf("write dma tlp size ERROR = %d\n", ret);
		}
		
	  Read_FPGA_VER();	
		
	  printf("tInit finished\n");
	 	
}


void tDMAStart(int mode )
{

       int ret;
	   
	   int  start = 0x1;
	   
        // config dma work mode , bit0=1 时表示板卡DMA写操作, bit0=0 时表示板卡DMA读操作
	    ret = ioctl(g_fd, WRDDMACR, mode);
		if ( ret == 0 )
		{
			//printf("config dma work mode = %d\n",mode);
		}
		else
		{
			printf("config dma work mode  ERROR = %d\n", ret);
		}

        // DMA Command lock,Start DMA,  bit0=1 时命令锁存
	    ret = ioctl(g_fd, WRDDMAST, start);
		if ( ret == 0 )
		{
			//printf("DMA Command locked, Start DMA OK! \n");
		}
		else
		{

			printf("DMA Command unlocked ERROR = %d\n", ret);
		}

}


void Disable_DMA_Trans( )
{      
	    
		int ret;
	    ret = ioctl(g_fd, USR_DMA_END, DIS_DMA_TRANS);
		if ( ret == 0 )
		{
			printf("USER Disable DMA Transfer OK %d\n");
		}
		else
		{
			printf("USER Disable DMA Transfer ERROR = %d\n", ret);
		}
}

int Read_DMA_STATUS( )
{      
	    
		int ret;
		int Status;
		
	      ret = ioctl(g_fd, DMASTATUS, &Status);
		if ( ret == 0 )
		{
			printf("READ DMA STATUS REG  = %d\n",Status);
		}
		else
		{
			printf("USER Disable DMA Transfer ERROR = %d\n", ret);
			return  ret;
		}
		
		return Status;
}


int Read_DMAWR_CLKNUM( )
{      
	    
		int ret;
		int clknum;
		
	    ret = ioctl(g_fd, RDDMAWRTLPCLKN, &clknum);
		if ( ret == 0 )
		{
			printf("READ DMA WRTIE TLP CLK NUMBER  = %d\n",clknum);
		}
		else
		{
			printf("READ DMA WRTIE TLP CLK NUMBER ERROR = %d\n", ret);
			return  ret;
		}
		
		return clknum;
}



int Read_DMARD_CLKNUM( )
{      
	    
		int ret;
		int clknum;
		
	    ret = ioctl(g_fd, DMARD_CLKNUM_RDREG, &clknum);
		if ( ret == 0 )
		{
			printf("READ DMA READ TLP CLK NUMBER  = %d\n",clknum);
		}
		else
		{
			printf("READ DMA READ TLP CLK NUMBER ERROR = %d\n", ret);
			//return  ret;
		}
		
		return clknum;
}




void tUpdateID( )
{      
	    
		int ret;
		
	    ret = ioctl(g_fd, USR_ID_UP, 0x55);
		if ( ret == 0 )
		{
			//printf("UPdate ID OK!\n");
		}
		else
		{
			printf("UPdate ID ERROR = %d\n", ret);
			//return  ret;
		}
		
		//return vernum;
}




void tDMAStop()
{
	
	    int cnt = 0;
	    int bit, temp;
	  
        Disable_DMA_Trans(); 
		
		do
		{
			if(cnt++ == 1000)
			{
				printf("USER Disable DMA Transfer failure \n");
				return ;
			}
			
			temp =  Read_DMA_STATUS();
			bit  =  temp & 0x40;
		} while(bit != 0x40); 
	  
	
}



#if 0
int main()
{
	// 定义一个变量作为函数的返回值
	int return_value = 0;
	
	int ret = 0;

      int  i = 0;
	
	unsigned char buf[buf_size+1];
      unsigned char kbuf[buf_size+1];
	
	// 判断用户输入的参数是否符合要求
/*
	if (argc < 2)
	{
		printf("Message : Please input more arguments.\n");
		return_value = -1;
		return return_value;
	}
*/
	
	// 得到文件名称：desfilename是目标文件
	//const char *desfilename = args[1];
	// 打开文件
         
	FILE *pdes0 = fopen("ch0.bin", "w");
       FILE *pdes1 = fopen("ch1.bin", "w");
	// 判断打开文件是否成tRecv功

	if (pdes0 == NULL)
	{
		printf("Message : %s open failed\n", pdes0);
		return_value = -1;
		return return_value;
	}

	if (pdes1 == NULL)
	{
		printf("Message : %s open failed\n", pdes1);
		return_value = -1;
		return return_value;
	}
	
      tOpen();
	tInit();
	tUpdateID();
	struct timeval tv;
	struct timeval start_tv;
	struct timeval end_tv;
//      tDMAStart(1);
         unsigned char tongdaohao =0;
	// 循环读取并复制文件
	unsigned int mycount = 1024*1024;
	unsigned int recvcount = 0;
	unsigned int writecount = 0;
	unsigned int writecount_sum = 0;
	gettimeofday(&tv,NULL);

	start_tv.tv_sec = tv.tv_sec;
	start_tv.tv_usec = tv.tv_usec;
	while (mycount--)
	{
		 tDMAStart(1);
		// 清空缓冲区内存
            while(Read_Chan_NUM() == 0x55);
//		memset(buf, 0, sizeof(buf));
		ret = read(g_fd, (void*)&buf, sizeof(buf));
		tongdaohao = buf[0];
		recvcount++;
		tUpdateID();

            if ( ret == 0 )
		{ 
	        
//			for( i = 0; i< sizeof(buf); i++)
//			{	
//				printf("0x%x ", buf[i]);
//			}

              //memcpy(kbuf, &buf, sizeof(buf));
                 for(i=0; i< sizeof(buf)-1;i++)
                       kbuf[i] = buf[i+1]; 
	     
             if(tongdaohao ==0)
		// 将缓冲区中的内容写入到文件
                    {
//                     printf("FILE 0 ENTER\n ");
		    fwrite(kbuf, sizeof(char), sizeof(buf)-1, pdes0);
                     }
              else if(tongdaohao ==1)
                      {
//                         printf("FILE 1 ENTER\n ");
		     fwrite(kbuf, sizeof(char), sizeof(buf)-1, pdes1);
    		     writecount = fwrite(&kbuf[1],4, 256, pdes1);
                     } 

		}
		else{
			 printf("Message : Read DMA Buffer failure\n");
		     return_value = -1;
		     return return_value;	
		}
		writecount_sum+= writecount;
	}
	gettimeofday(&tv,NULL);
	end_tv.tv_sec = tv.tv_sec;
	end_tv.tv_usec = tv.tv_usec;

	printf("cost second %lld,usecond %lld\n",end_tv.tv_sec - start_tv.tv_sec,end_tv.tv_usec - start_tv.tv_usec);
	printf("recvcout :%d\n",recvcount);

	printf("writecount_sum :%d\n",writecount_sum);

	printf("writebyte_sum :%d\n",writecount_sum*4);
		
	// 关闭文件
	fclose(pdes0);
      fclose(pdes1);
	printf("file open over!\n");	
	return return_value;
}
#endif

int main()
{
	int return_value = 0;
	
	int ret = 0;

      int  i = 0;

	struct timeval tv;
	struct timeval start_tv;
	struct timeval end_tv;

      unsigned char tongdaohao =0;
	unsigned int mycount = 102400;
	unsigned int recvcount = 0;

	unsigned int writebyte = 0;
	unsigned int writebyte_sum = 0;

	unsigned int writebyte1 = 0;
	unsigned int writebyte_sum1 = 0;

	unsigned char buf[buf_size];
  
#if 0
	int myfd = open("/mnt/raid0/Data/chann0.bin",O_RDWR | O_CREAT,0777);
	if(myfd < 0)
	{
		printf("open file error!\n");
	}
	int j = 0;

	char sendbuff[1*1024*1024];

	gettimeofday(&start_tv,NULL);
	for(j = 0;j<mycount;j++)
	{
		writebyte = write(myfd,sendbuff,1*1024*1024);
		writebyte_sum+= writebyte;
	}
	gettimeofday(&end_tv,NULL);

	printf("writebyte_sum is %d/n",writebyte_sum);
	printf("cost second :%lld,usecond : %lld\n",end_tv.tv_sec - start_tv.tv_sec,end_tv.tv_usec - start_tv.tv_usec);
	close(myfd);
	while(1);
#endif
	int fd = open("chann0.bin",O_RDWR | O_CREAT,0777);
	if(fd < 0)
	{
		printf("open file error!\n");
	}
	int fd1 = open("chann1.bin",O_RDWR | O_CREAT,0777);
	if(fd1 < 0)
	{
		printf("open file error!\n");
	}

      tOpen();
	tInit();
	tUpdateID();
	
	gettimeofday(&tv,NULL);

	start_tv.tv_sec = tv.tv_sec;
	start_tv.tv_usec = tv.tv_usec;

	while (1)
	{
		tDMAStart(1);

             while(Read_Chan_NUM() == 0x55);
//		printf("before read tongdaohao is %d\n",Read_Chan_NUM());
		ret = read(g_fd, (void*)buf, sizeof(buf));
		//printf("recv data!\n");
		tongdaohao = Read_Chan_NUM();
	//	tongdaohao = 0;
		//printf("speed is %dMB/s\n",1000000000*2/Read_DMAWR_CLKNUM()/1024/1024);
		//Read_DMAWR_CLKNUM();
		recvcount++;

		tUpdateID();
#if 0
            if (ret == 0 )
		{      
               if(tongdaohao ==0)
                      {
				writebyte = write(fd,buf,buf_size);
//				printf("writebyte  is %d\n",writebyte);
				if(writebyte < 0)
				{
					printf("write file failed!\n");
				}
				else
				{			
					writebyte_sum += writebyte;
				}
                     } 
   		   if(tongdaohao ==1)
                      {
				writebyte1 = write(fd1,buf,buf_size);
//				printf("writebyte1  is %d\n",writebyte1);
				if(writebyte < 0)
				{
					printf("write file failed!\n");
				}
				else
				{			
					writebyte_sum1 += writebyte1;
				}
                     } 
		}
		else
		{
			printf("Message : Read DMA Buffer failure\n");
		     return_value = -1;
		     return return_value;	
		}
#endif
	}

	gettimeofday(&tv,NULL);
	end_tv.tv_sec = tv.tv_sec;
	end_tv.tv_usec = tv.tv_usec;

	printf("cost second %lld,usecond %lld\n",end_tv.tv_sec - start_tv.tv_sec,end_tv.tv_usec - start_tv.tv_usec);
	printf("recvcout :%d\n",recvcount);
	printf("writebyte_sum :%lld ,speed is:%d MByte/s \n",writebyte_sum,writebyte_sum/(end_tv.tv_sec - start_tv.tv_sec)/1024/1024);
	
	// 关闭文件
	close(fd);
	close(fd1);
	printf("file close over!\n");	
	return return_value;
}


/*
int main()
{
	int tmp;

      tOpen();
	tInit();
    	
     while(1)
      {
      tUpdateID();	
      tDMAStart(1);//DMA WRITE 	
       while(Read_Chan_NUM() == 0x55 );
             tRecv();	
	//sleep(1);
      }

	return 0;
}
*/

